﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using FarseerPhysics.Dynamics;
using FarseerPhysics.Dynamics.Contacts;
using Animation;
using MapLibrary.Players;
using AI;
using FarseerPhysics;
using FarseerPhysics.Dynamics.Joints;
using FarseerPhysics.Factories;
using Microsoft.Xna.Framework;
using MapLibrary.Particles;
using MapLibrary;

namespace Enemies
{
    class TuberculosisSpit : Sprite
    {
        /// <summary>
        /// the amount of linear damping to apply when a tuberculosisspit gets stuck to the player
        /// </summary>
        const float DAMPING = 3.0f;
        
        public Sprite Owner { get; set; }

        /// <summary>
        /// the joint to be used when the spit collides with the player
        /// </summary>
        private WeldJoint joint;

        public TuberculosisSpit()
        {
            MAX_VELOCITY_X = ConvertUnits.ToSimUnits(1000);
            MAX_VELOCITY_Y = ConvertUnits.ToSimUnits(1000);
            this.Controller.MaxLinearVelocityX = MAX_VELOCITY_X;
            this.Controller.MaxLinearVelocityY = MAX_VELOCITY_Y;

            CollisionCategory = MapLibrary.Players.CollisionResponse.CollisionResponseManager.CollisionCategory.TuberculosisSpit;

            Hookable = false;
        }

        /// <summary>
        /// if the spit collides with the player, create a joint between them and increase the players linear damping
        /// if the spit collides with anything else, remove it from the world and recycle it
        /// </summary>
        /// <param name="f1"></param>
        /// <param name="f2"></param>
        /// <param name="contact"></param>
        /// <returns></returns>
        public override bool MyOnCollision(Fixture f1, Fixture f2, Contact contact)
        {
            Sprite s1 = f1.Body.UserData as Sprite;
            Sprite s2 = f2.Body.UserData as Sprite;

            if (s2 == null)
            {
                TuberculosisSpit ts = s1 as TuberculosisSpit;
                TuberculosisBot b = ts.Owner.Bot as TuberculosisBot;

                

                if (joint != null)
                {
                    World w = World.PhysicsWorld;
                    w.RemoveJoint(joint);
                    OnJointBreak(joint, 0);
                    joint = null;
                    return false;
                }
                else
                {
                    b.RecycleAmmo(this);
                    World.CurrentLevel.RemoveSprite(this);
                    World.CurrentLevel.AddBodyToDisable(this);
                    return false;
                }
                /*
                LevelCollisionRegion region = f2.Body.UserData as LevelCollisionRegion;
                if (region != null)
                {
                    s1.Body.LinearVelocity = Vector2.Zero;
                    World w = World.PhysicsWorld;
                    s1.Body.FixedRotation = false;

                    if (joint == null)
                    {
                        joint = JointFactory.CreateWeldJoint(w, region.Body, s1.Body, Vector2.Zero, region.Body.Position - s1.Body.Position);
                        joint.Broke += OnJointBreak;
                        s1.Body.IgnoreGravity = true;
                    }
                    return false;
                }
                else
                    return false;*/
            }

            if (s2 == Owner)
            {
                return false;
            }
            else
            {
                if (s2.Equals(World.CurrentLevel.Player))
                {
                    s1.Body.LinearVelocity = Vector2.Zero;
                    World w = World.PhysicsWorld;

                    if (joint == null)
                    {
                        s1.Body.FixedRotation = false;
                        joint = JointFactory.CreateWeldJoint(w, s2.Body, s1.Body, Vector2.Zero, s2.Body.Position - s1.Body.Position);
                        joint.Broke += OnJointBreak;
                        s1.Body.IgnoreGravity = true;
                    }
                    float damp = s2.Body.LinearDamping;
                    damp += DAMPING;
                    s2.Body.LinearDamping = damp;
                }
                else
                {
                    TuberculosisSpit ts = s1 as TuberculosisSpit;
                    TuberculosisBot b = ts.Owner.Bot as TuberculosisBot;

                    World.CurrentLevel.RemoveSprite(this);
                    World.CurrentLevel.AddBodyToDisable(this);

                    if (b != null)
                        b.RecycleAmmo(this);
                    Owner.World.CurrentLevel.RemoveSprite(this);

                    if (joint != null)
                    {
                        World w = World.PhysicsWorld;
                        w.RemoveJoint(joint);
                        OnJointBreak(joint, 0);
                        joint = null;
                    }
                }
            }

            return false;
        }

        /// <summary>
        /// Gets called when the joint between a TuberculosisSpit and the player breaks
        /// </summary>
        /// <param name="j"></param>
        /// <param name="f"></param>
        public void OnJointBreak(Joint j, float f)
        {
            TuberculosisBot b = Owner.Bot as TuberculosisBot;
            World.CurrentLevel.RemoveSprite(this);

            World.CurrentLevel.AddBodyToDisable(this);

            b.RecycleAmmo(this);
            Owner.World.CurrentLevel.RemoveSprite(this);
            joint = null;
            float damp = World.CurrentLevel.Player.Body.LinearDamping;
            damp -= DAMPING;
            World.CurrentLevel.Player.Body.LinearDamping = damp;
        }


    }
}
